1 Getting the query fasta file

curl https://owl.fish.washington.edu/halfshell/genomic-databank/GCF_031168955.1_ASM3116895v1_genomic.fna\
-k \
> ../data/GCF_031168955.1_ASM3116895v1_genomic.fna

Exploring what fasta file

head -3 ../data/GCF_031168955.1_ASM3116895v1_genomic.fna
## >NC_082382.1 Gadus macrocephalus chromosome 1, ASM3116895v1
## CAGACCTCCAATAGAGAGCTGCTCCCCCTTCGCACAAAGCCGCTGCTGGTGAATGCTCGAAGCGTTGTGTGATTGAATCG
## CTTTAATGCCGTTCCATGTCACGTTGATCGTTTTTTTGCACAACGAGCAAAAAGCTTCCCGGTCATTTCCCATCACGGGT
echo "How many sequences are there?"
grep -c ">" ../data/GCF_031168955.1_ASM3116895v1_genomic.fna
## How many sequences are there?
## 24

We want sequences for every gene. Thus, we need to use the genome fasta and gff to extract fastas for every entry in the gtf.

/home/shared/bedtools2/bin/bedtools getfasta -fi ../data/GCF_031168955.1_ASM3116895v1_genomic.fna -bed ../data/GCF_031168955.1_ASM3116895v1.gff -fo ../data/Gmac_genes_fasta.fasta

2 Database Creation

2.1 Obtain Fasta (UniProt/Swiss-Prot)

This is from here picur reviewe sequences I named based on the identify of the database given

cd ../data
curl -O https://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/complete/uniprot_sprot.fasta.gz
mv uniprot_sprot.fasta.gz uniprot_sprot_r2023_04.fasta.gz
gunzip -k uniprot_sprot_r2023_04.fasta.gz

curl -O https://gannet.fish.washington.edu/seashell/snaps/uniprot_table_r2023_01.tab

2.2 Making the database

mkdir ../blastdb
/home/shared/ncbi-blast-2.11.0+/bin/makeblastdb \
-in ../data/uniprot_sprot_r2023_04.fasta \
-dbtype prot \
-out ../blastdb/uniprot_sprot_r2023_04

3 Running Blastx

/home/shared/ncbi-blast-2.11.0+/bin/blastx \
-query ../data/Gmac_genes_fasta.fasta \
-db ../blastdb/uniprot_sprot_r2023_04 \
-out ../output/03.2-genome-annotation/Gmac.genesfasta-uniprot_blastx.tab \
-evalue 1E-20 \
-num_threads 20 \
-max_target_seqs 1 \
-outfmt 6 \
&> ../output/03.2-genome-annotation/Gmac.genesfasta-uniprot_blastx.log
head -2 ../output/03.2-genome-annotation/Gmac.genesfasta-uniprot_blastx.tab
## NC_082382.1:0-26289739   sp|Q9NYQ7|CELR3_HUMAN   77.838  925 203 1   20384275    20381507    325 1249    0.0 1381
## NC_082382.1:0-26289739   sp|Q9NYQ7|CELR3_HUMAN   31.884  828 520 17  20383957    20381549    323 1131    1.84e-74    295
echo "Number of lines in output"
wc -l ../output/03.2-genome-annotation/Gmac.genesfasta-uniprot_blastx.tab
## Number of lines in output
## 18650 ../output/03.2-genome-annotation/Gmac.genesfasta-uniprot_blastx.tab

4 Joining Blast table with annoations.

4.1 Prepping Blast table for easy join

tr '|' '\t' < ../output/03.2-genome-annotation/Gmac.genesfasta-uniprot_blastx.tab \
> ../output/03.2-genome-annotation/Gmac.genesfasta-uniprot_blastx_sep.tab

head -1 ../output/03.2-genome-annotation/Gmac.genesfasta-uniprot_blastx_sep.tab
## NC_082382.1:0-26289739   sp  Q9NYQ7  CELR3_HUMAN 77.838  925 203 1   20384275    20381507    325 1249    0.0 1381

4.2 Could do some cool stuff in R here reading in table

bltabl <- read.csv("../output/03.2-genome-annotation/Gmac.genesfasta-uniprot_blastx_sep.tab", sep = '\t', header = FALSE)

spgo <- read.csv("../data/uniprot_table_r2023_01.tab", sep = '\t', header = TRUE)
datatable(head(bltabl), options = list(scrollX = TRUE, scrollY = "400px", scrollCollapse = TRUE, paging = FALSE))
datatable(head(spgo), options = list(scrollX = TRUE, scrollY = "400px", scrollCollapse = TRUE, paging = FALSE))
datatable(
  left_join(bltabl, spgo,  by = c("V3" = "Entry")) %>%
  select(V1, V3, V13, Protein.names, Organism, Gene.Ontology..biological.process., Gene.Ontology.IDs) 
 # %>% mutate(V1 = str_replace_all(V1,pattern = "solid0078_20110412_FRAG_BC_WHITE_WHITE_F3_QV_SE_trimmed", replacement = "Ab"))
)
annot_tab <-
  left_join(bltabl, spgo,  by = c("V3" = "Entry")) %>%
  select(V1, V3, V13, Protein.names, Organism, Gene.Ontology..biological.process., Gene.Ontology.IDs)

write.table(annot_tab, file = "../output/03.2-genome-annotation/G_macrocephalus_genes_IDmapping_2024_04_17.tab", sep = "\t",
            row.names = TRUE, col.names = NA)
head -n 3 ../output/03.2-genome-annotation/G_macrocephalus_genes_IDmapping_2024_04_17.tab
# Read dataset
#dataset <- read.csv("../output/blast_annot_go.tab", sep = '\t')  # Replace with the path to your dataset

# Select the column of interest
column_name <- "Organism"  # Replace with the name of the column of interest
column_data <- annot_tab[[column_name]]

# Count the occurrences of the strings in the column
string_counts <- table(column_data)

# Convert to a data frame, sort by count, and select the top 10
string_counts_df <- as.data.frame(string_counts)
colnames(string_counts_df) <- c("String", "Count")
string_counts_df <- string_counts_df[order(string_counts_df$Count, decreasing = TRUE), ]
top_10_strings <- head(string_counts_df, n = 10)

# Plot the top 10 most common strings using ggplot2
ggplot(top_10_strings, aes(x = reorder(String, -Count), y = Count, fill = String)) +
  geom_bar(stat = "identity", position = "dodge", color = "black") +
  labs(title = "Top 10 Species hits",
       x = column_name,
       y = "Count") +
  theme_minimal() +
  theme(legend.position = "none") +
  coord_flip()

#data <- read.csv("../output/blast_annot_go.tab", sep = '\t')

# Rename the `Gene.Ontology..biological.process.` column to `Biological_Process`
colnames(annot_tab)[colnames(annot_tab) == "Gene.Ontology..biological.process."] <- "Biological_Process"

# Separate the `Biological_Process` column into individual biological processes
data_separated <- unlist(strsplit(annot_tab$Biological_Process, split = ";"))

# Trim whitespace from the biological processes
data_separated <- gsub("^\\s+|\\s+$", "", data_separated)

# Count the occurrences of each biological process
process_counts <- table(data_separated)
process_counts <- data.frame(Biological_Process = names(process_counts), Count = as.integer(process_counts))
process_counts <- process_counts[order(-process_counts$Count), ]

# Select the 20 most predominant biological processes
top_20_processes <- process_counts[1:20, ]

# Create a color palette for the bars
bar_colors <- rainbow(nrow(top_20_processes))

# Create a staggered vertical bar plot with different colors for each bar
barplot(top_20_processes$Count, names.arg = rep("", nrow(top_20_processes)), col = bar_colors,
        ylim = c(0, max(top_20_processes$Count) * 1.25),
        main = "Occurrences of the 20 Most Predominant Biological Processes", xlab = "Biological Process", ylab = "Count")

# Create a separate plot for the legend
png("../output/GOlegend.png", width = 800, height = 600)
par(mar = c(0, 0, 0, 0))
plot.new()
legend("center", legend = top_20_processes$Biological_Process, fill = bar_colors, cex = 1, title = "Biological Processes")
dev.off()
## png 
##   2
knitr::include_graphics("../output/GOlegend.png")

LS0tCnRpdGxlOiAiMDMuMi1nZW5vbWUtYW5ub3RhdGlvbiIKYXV0aG9yOiBTdGV2ZW4gUm9iZXJ0cwpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiIAphbHdheXNfYWxsb3dfaHRtbDogdHJ1ZQpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZTogcmVhZGFibGUKICAgIGhpZ2hsaWdodDogemVuYnVybgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgZ2l0aHViX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgaHRtbF9wcmV2aWV3OiB0cnVlCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoa25pdHIpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoRFQpCmxpYnJhcnkoQmlvc3RyaW5ncykKbGlicmFyeSh0bSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBUUlVFLCAgICAgICAgICMgRGlzcGxheSBjb2RlIGNodW5rcwogIGV2YWwgPSBGQUxTRSwgICAgICAgICAjIEV2YWx1YXRlIGNvZGUgY2h1bmtzCiAgd2FybmluZyA9IEZBTFNFLCAgICAgIyBIaWRlIHdhcm5pbmdzCiAgbWVzc2FnZSA9IEZBTFNFLCAgICAgIyBIaWRlIG1lc3NhZ2VzCiAgZmlnLndpZHRoID0gNiwgICAgICAgIyBTZXQgcGxvdCB3aWR0aCBpbiBpbmNoZXMKICBmaWcuaGVpZ2h0ID0gNCwgICAgICAjIFNldCBwbG90IGhlaWdodCBpbiBpbmNoZXMKICBmaWcuYWxpZ24gPSAiY2VudGVyIiAjIEFsaWduIHBsb3RzIHRvIHRoZSBjZW50ZXIKKQpgYGAKCgoKIyBHZXR0aW5nIHRoZSBxdWVyeSBmYXN0YSBmaWxlCgpgYGB7ciBkb3dubG9hZC1xdWVyeSwgZW5naW5lPSdiYXNoJ30KY3VybCBodHRwczovL293bC5maXNoLndhc2hpbmd0b24uZWR1L2hhbGZzaGVsbC9nZW5vbWljLWRhdGFiYW5rL0dDRl8wMzExNjg5NTUuMV9BU00zMTE2ODk1djFfZ2Vub21pYy5mbmFcCi1rIFwKPiAuLi9kYXRhL0dDRl8wMzExNjg5NTUuMV9BU00zMTE2ODk1djFfZ2Vub21pYy5mbmEKYGBgCgpFeHBsb3Jpbmcgd2hhdCBmYXN0YSBmaWxlCgpgYGB7ciB2aWV3LXF1ZXJ5LCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CmhlYWQgLTMgLi4vZGF0YS9HQ0ZfMDMxMTY4OTU1LjFfQVNNMzExNjg5NXYxX2dlbm9taWMuZm5hCmBgYAoKYGBge3IgdmlldzItcXVlcnksIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KZWNobyAiSG93IG1hbnkgc2VxdWVuY2VzIGFyZSB0aGVyZT8iCmdyZXAgLWMgIj4iIC4uL2RhdGEvR0NGXzAzMTE2ODk1NS4xX0FTTTMxMTY4OTV2MV9nZW5vbWljLmZuYQpgYGAKV2Ugd2FudCBzZXF1ZW5jZXMgZm9yIGV2ZXJ5IGdlbmUuIFRodXMsIHdlIG5lZWQgdG8gdXNlIHRoZSBnZW5vbWUgZmFzdGEgYW5kIGdmZiB0byBleHRyYWN0IGZhc3RhcyBmb3IgZXZlcnkgZW50cnkgaW4gdGhlIGd0Zi4KYGBge3IgZ2V0LXJlZmVyZW5jZS1mYXN0YXMsIGVuZ2luZT0nYmFzaCd9Ci9ob21lL3NoYXJlZC9iZWR0b29sczIvYmluL2JlZHRvb2xzIGdldGZhc3RhIC1maSAuLi9kYXRhL0dDRl8wMzExNjg5NTUuMV9BU00zMTE2ODk1djFfZ2Vub21pYy5mbmEgLWJlZCAuLi9kYXRhL0dDRl8wMzExNjg5NTUuMV9BU00zMTE2ODk1djEuZ2ZmIC1mbyAuLi9kYXRhL0dtYWNfZ2VuZXNfZmFzdGEuZmFzdGEKYGBgCgojIERhdGFiYXNlIENyZWF0aW9uCgojIyBPYnRhaW4gRmFzdGEgKFVuaVByb3QvU3dpc3MtUHJvdCkKClRoaXMgaXMgZnJvbSBoZXJlIHBpY3VyIHJldmlld2Ugc2VxdWVuY2VzIEkgbmFtZWQgYmFzZWQgb24gdGhlIGlkZW50aWZ5IG9mIHRoZSBkYXRhYmFzZSBnaXZlbgoKCgpgYGB7ciBkb3dubG9hZC1kYXRhLCBlbmdpbmU9J2Jhc2gnfQpjZCAuLi9kYXRhCmN1cmwgLU8gaHR0cHM6Ly9mdHAudW5pcHJvdC5vcmcvcHViL2RhdGFiYXNlcy91bmlwcm90L2N1cnJlbnRfcmVsZWFzZS9rbm93bGVkZ2ViYXNlL2NvbXBsZXRlL3VuaXByb3Rfc3Byb3QuZmFzdGEuZ3oKbXYgdW5pcHJvdF9zcHJvdC5mYXN0YS5neiB1bmlwcm90X3Nwcm90X3IyMDIzXzA0LmZhc3RhLmd6Cmd1bnppcCAtayB1bmlwcm90X3Nwcm90X3IyMDIzXzA0LmZhc3RhLmd6CgpjdXJsIC1PIGh0dHBzOi8vZ2FubmV0LmZpc2gud2FzaGluZ3Rvbi5lZHUvc2Vhc2hlbGwvc25hcHMvdW5pcHJvdF90YWJsZV9yMjAyM18wMS50YWIKYGBgCgojIyBNYWtpbmcgdGhlIGRhdGFiYXNlCgpgYGB7ciBtYWtlLWJsYXN0ZGIsIGVuZ2luZT0nYmFzaCd9Cm1rZGlyIC4uL2JsYXN0ZGIKL2hvbWUvc2hhcmVkL25jYmktYmxhc3QtMi4xMS4wKy9iaW4vbWFrZWJsYXN0ZGIgXAotaW4gLi4vZGF0YS91bmlwcm90X3Nwcm90X3IyMDIzXzA0LmZhc3RhIFwKLWRidHlwZSBwcm90IFwKLW91dCAuLi9ibGFzdGRiL3VuaXByb3Rfc3Byb3RfcjIwMjNfMDQKYGBgCgoKCgojIFJ1bm5pbmcgQmxhc3R4CgpgYGB7ciBibGFzdHgsIGVuZ2luZT0nYmFzaCd9Ci9ob21lL3NoYXJlZC9uY2JpLWJsYXN0LTIuMTEuMCsvYmluL2JsYXN0eCBcCi1xdWVyeSAuLi9kYXRhL0dtYWNfZ2VuZXNfZmFzdGEuZmFzdGEgXAotZGIgLi4vYmxhc3RkYi91bmlwcm90X3Nwcm90X3IyMDIzXzA0IFwKLW91dCAuLi9vdXRwdXQvMDMuMi1nZW5vbWUtYW5ub3RhdGlvbi9HbWFjLmdlbmVzZmFzdGEtdW5pcHJvdF9ibGFzdHgudGFiIFwKLWV2YWx1ZSAxRS0yMCBcCi1udW1fdGhyZWFkcyAyMCBcCi1tYXhfdGFyZ2V0X3NlcXMgMSBcCi1vdXRmbXQgNiBcCiY+IC4uL291dHB1dC8wMy4yLWdlbm9tZS1hbm5vdGF0aW9uL0dtYWMuZ2VuZXNmYXN0YS11bmlwcm90X2JsYXN0eC5sb2cKYGBgCgpgYGB7ciBibGFzdC1sb29rLCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CmhlYWQgLTIgLi4vb3V0cHV0LzAzLjItZ2Vub21lLWFubm90YXRpb24vR21hYy5nZW5lc2Zhc3RhLXVuaXByb3RfYmxhc3R4LnRhYgpgYGAKCmBgYHtyIGJsYXN0LWxvb2syLCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CmVjaG8gIk51bWJlciBvZiBsaW5lcyBpbiBvdXRwdXQiCndjIC1sIC4uL291dHB1dC8wMy4yLWdlbm9tZS1hbm5vdGF0aW9uL0dtYWMuZ2VuZXNmYXN0YS11bmlwcm90X2JsYXN0eC50YWIKYGBgCgoKCgojIEpvaW5pbmcgQmxhc3QgdGFibGUgd2l0aCBhbm5vYXRpb25zLgoKIyMgUHJlcHBpbmcgQmxhc3QgdGFibGUgZm9yIGVhc3kgam9pbgoKYGBge3Igc2VwYXJhdGUsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KdHIgJ3wnICdcdCcgPCAuLi9vdXRwdXQvMDMuMi1nZW5vbWUtYW5ub3RhdGlvbi9HbWFjLmdlbmVzZmFzdGEtdW5pcHJvdF9ibGFzdHgudGFiIFwKPiAuLi9vdXRwdXQvMDMuMi1nZW5vbWUtYW5ub3RhdGlvbi9HbWFjLmdlbmVzZmFzdGEtdW5pcHJvdF9ibGFzdHhfc2VwLnRhYgoKaGVhZCAtMSAuLi9vdXRwdXQvMDMuMi1nZW5vbWUtYW5ub3RhdGlvbi9HbWFjLmdlbmVzZmFzdGEtdW5pcHJvdF9ibGFzdHhfc2VwLnRhYgoKYGBgCgojIyBDb3VsZCBkbyBzb21lIGNvb2wgc3R1ZmYgaW4gUiBoZXJlIHJlYWRpbmcgaW4gdGFibGUKCmBgYHtyIHJlYWQtZGF0YSwgZXZhbD1UUlVFLCBjYWNoZT1UUlVFfQpibHRhYmwgPC0gcmVhZC5jc3YoIi4uL291dHB1dC8wMy4yLWdlbm9tZS1hbm5vdGF0aW9uL0dtYWMuZ2VuZXNmYXN0YS11bmlwcm90X2JsYXN0eF9zZXAudGFiIiwgc2VwID0gJ1x0JywgaGVhZGVyID0gRkFMU0UpCgpzcGdvIDwtIHJlYWQuY3N2KCIuLi9kYXRhL3VuaXByb3RfdGFibGVfcjIwMjNfMDEudGFiIiwgc2VwID0gJ1x0JywgaGVhZGVyID0gVFJVRSkKYGBgCgpgYGB7ciwgZXZhbD1UUlVFfQpkYXRhdGFibGUoaGVhZChibHRhYmwpLCBvcHRpb25zID0gbGlzdChzY3JvbGxYID0gVFJVRSwgc2Nyb2xsWSA9ICI0MDBweCIsIHNjcm9sbENvbGxhcHNlID0gVFJVRSwgcGFnaW5nID0gRkFMU0UpKQpgYGAKCmBgYHtyIHNwZ28tdGFibGUsIGV2YWw9VFJVRX0KZGF0YXRhYmxlKGhlYWQoc3BnbyksIG9wdGlvbnMgPSBsaXN0KHNjcm9sbFggPSBUUlVFLCBzY3JvbGxZID0gIjQwMHB4Iiwgc2Nyb2xsQ29sbGFwc2UgPSBUUlVFLCBwYWdpbmcgPSBGQUxTRSkpCmBgYAoKYGBge3Igc2VlLCBldmFsPVRSVUV9CmRhdGF0YWJsZSgKICBsZWZ0X2pvaW4oYmx0YWJsLCBzcGdvLCAgYnkgPSBjKCJWMyIgPSAiRW50cnkiKSkgJT4lCiAgc2VsZWN0KFYxLCBWMywgVjEzLCBQcm90ZWluLm5hbWVzLCBPcmdhbmlzbSwgR2VuZS5PbnRvbG9neS4uYmlvbG9naWNhbC5wcm9jZXNzLiwgR2VuZS5PbnRvbG9neS5JRHMpIAogIyAlPiUgbXV0YXRlKFYxID0gc3RyX3JlcGxhY2VfYWxsKFYxLHBhdHRlcm4gPSAic29saWQwMDc4XzIwMTEwNDEyX0ZSQUdfQkNfV0hJVEVfV0hJVEVfRjNfUVZfU0VfdHJpbW1lZCIsIHJlcGxhY2VtZW50ID0gIkFiIikpCikKYGBgCgpgYGB7ciBqb2luLCBldmFsPVRSVUV9CmFubm90X3RhYiA8LQogIGxlZnRfam9pbihibHRhYmwsIHNwZ28sICBieSA9IGMoIlYzIiA9ICJFbnRyeSIpKSAlPiUKICBzZWxlY3QoVjEsIFYzLCBWMTMsIFByb3RlaW4ubmFtZXMsIE9yZ2FuaXNtLCBHZW5lLk9udG9sb2d5Li5iaW9sb2dpY2FsLnByb2Nlc3MuLCBHZW5lLk9udG9sb2d5LklEcykKCndyaXRlLnRhYmxlKGFubm90X3RhYiwgZmlsZSA9ICIuLi9vdXRwdXQvMDMuMi1nZW5vbWUtYW5ub3RhdGlvbi9HX21hY3JvY2VwaGFsdXNfZ2VuZXNfSURtYXBwaW5nXzIwMjRfMDRfMTcudGFiIiwgc2VwID0gIlx0IiwKICAgICAgICAgICAgcm93Lm5hbWVzID0gVFJVRSwgY29sLm5hbWVzID0gTkEpCmBgYAoKYGBge2Jhc2h9CmhlYWQgLW4gMyAuLi9vdXRwdXQvMDMuMi1nZW5vbWUtYW5ub3RhdGlvbi9HX21hY3JvY2VwaGFsdXNfZ2VuZXNfSURtYXBwaW5nXzIwMjRfMDRfMTcudGFiCmBgYAoKYGBge3IsIGV2YWw9VFJVRX0KIyBSZWFkIGRhdGFzZXQKI2RhdGFzZXQgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9ibGFzdF9hbm5vdF9nby50YWIiLCBzZXAgPSAnXHQnKSAgIyBSZXBsYWNlIHdpdGggdGhlIHBhdGggdG8geW91ciBkYXRhc2V0CgojIFNlbGVjdCB0aGUgY29sdW1uIG9mIGludGVyZXN0CmNvbHVtbl9uYW1lIDwtICJPcmdhbmlzbSIgICMgUmVwbGFjZSB3aXRoIHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gb2YgaW50ZXJlc3QKY29sdW1uX2RhdGEgPC0gYW5ub3RfdGFiW1tjb2x1bW5fbmFtZV1dCgojIENvdW50IHRoZSBvY2N1cnJlbmNlcyBvZiB0aGUgc3RyaW5ncyBpbiB0aGUgY29sdW1uCnN0cmluZ19jb3VudHMgPC0gdGFibGUoY29sdW1uX2RhdGEpCgojIENvbnZlcnQgdG8gYSBkYXRhIGZyYW1lLCBzb3J0IGJ5IGNvdW50LCBhbmQgc2VsZWN0IHRoZSB0b3AgMTAKc3RyaW5nX2NvdW50c19kZiA8LSBhcy5kYXRhLmZyYW1lKHN0cmluZ19jb3VudHMpCmNvbG5hbWVzKHN0cmluZ19jb3VudHNfZGYpIDwtIGMoIlN0cmluZyIsICJDb3VudCIpCnN0cmluZ19jb3VudHNfZGYgPC0gc3RyaW5nX2NvdW50c19kZltvcmRlcihzdHJpbmdfY291bnRzX2RmJENvdW50LCBkZWNyZWFzaW5nID0gVFJVRSksIF0KdG9wXzEwX3N0cmluZ3MgPC0gaGVhZChzdHJpbmdfY291bnRzX2RmLCBuID0gMTApCgojIFBsb3QgdGhlIHRvcCAxMCBtb3N0IGNvbW1vbiBzdHJpbmdzIHVzaW5nIGdncGxvdDIKZ2dwbG90KHRvcF8xMF9zdHJpbmdzLCBhZXMoeCA9IHJlb3JkZXIoU3RyaW5nLCAtQ291bnQpLCB5ID0gQ291bnQsIGZpbGwgPSBTdHJpbmcpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siKSArCiAgbGFicyh0aXRsZSA9ICJUb3AgMTAgU3BlY2llcyBoaXRzIiwKICAgICAgIHggPSBjb2x1bW5fbmFtZSwKICAgICAgIHkgPSAiQ291bnQiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICBjb29yZF9mbGlwKCkKCgpgYGAKCmBgYHtyIGdvLCBldmFsPVRSVUV9CgoKI2RhdGEgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9ibGFzdF9hbm5vdF9nby50YWIiLCBzZXAgPSAnXHQnKQoKIyBSZW5hbWUgdGhlIGBHZW5lLk9udG9sb2d5Li5iaW9sb2dpY2FsLnByb2Nlc3MuYCBjb2x1bW4gdG8gYEJpb2xvZ2ljYWxfUHJvY2Vzc2AKY29sbmFtZXMoYW5ub3RfdGFiKVtjb2xuYW1lcyhhbm5vdF90YWIpID09ICJHZW5lLk9udG9sb2d5Li5iaW9sb2dpY2FsLnByb2Nlc3MuIl0gPC0gIkJpb2xvZ2ljYWxfUHJvY2VzcyIKCiMgU2VwYXJhdGUgdGhlIGBCaW9sb2dpY2FsX1Byb2Nlc3NgIGNvbHVtbiBpbnRvIGluZGl2aWR1YWwgYmlvbG9naWNhbCBwcm9jZXNzZXMKZGF0YV9zZXBhcmF0ZWQgPC0gdW5saXN0KHN0cnNwbGl0KGFubm90X3RhYiRCaW9sb2dpY2FsX1Byb2Nlc3MsIHNwbGl0ID0gIjsiKSkKCiMgVHJpbSB3aGl0ZXNwYWNlIGZyb20gdGhlIGJpb2xvZ2ljYWwgcHJvY2Vzc2VzCmRhdGFfc2VwYXJhdGVkIDwtIGdzdWIoIl5cXHMrfFxccyskIiwgIiIsIGRhdGFfc2VwYXJhdGVkKQoKIyBDb3VudCB0aGUgb2NjdXJyZW5jZXMgb2YgZWFjaCBiaW9sb2dpY2FsIHByb2Nlc3MKcHJvY2Vzc19jb3VudHMgPC0gdGFibGUoZGF0YV9zZXBhcmF0ZWQpCnByb2Nlc3NfY291bnRzIDwtIGRhdGEuZnJhbWUoQmlvbG9naWNhbF9Qcm9jZXNzID0gbmFtZXMocHJvY2Vzc19jb3VudHMpLCBDb3VudCA9IGFzLmludGVnZXIocHJvY2Vzc19jb3VudHMpKQpwcm9jZXNzX2NvdW50cyA8LSBwcm9jZXNzX2NvdW50c1tvcmRlcigtcHJvY2Vzc19jb3VudHMkQ291bnQpLCBdCgojIFNlbGVjdCB0aGUgMjAgbW9zdCBwcmVkb21pbmFudCBiaW9sb2dpY2FsIHByb2Nlc3Nlcwp0b3BfMjBfcHJvY2Vzc2VzIDwtIHByb2Nlc3NfY291bnRzWzE6MjAsIF0KCiMgQ3JlYXRlIGEgY29sb3IgcGFsZXR0ZSBmb3IgdGhlIGJhcnMKYmFyX2NvbG9ycyA8LSByYWluYm93KG5yb3codG9wXzIwX3Byb2Nlc3NlcykpCgojIENyZWF0ZSBhIHN0YWdnZXJlZCB2ZXJ0aWNhbCBiYXIgcGxvdCB3aXRoIGRpZmZlcmVudCBjb2xvcnMgZm9yIGVhY2ggYmFyCmJhcnBsb3QodG9wXzIwX3Byb2Nlc3NlcyRDb3VudCwgbmFtZXMuYXJnID0gcmVwKCIiLCBucm93KHRvcF8yMF9wcm9jZXNzZXMpKSwgY29sID0gYmFyX2NvbG9ycywKICAgICAgICB5bGltID0gYygwLCBtYXgodG9wXzIwX3Byb2Nlc3NlcyRDb3VudCkgKiAxLjI1KSwKICAgICAgICBtYWluID0gIk9jY3VycmVuY2VzIG9mIHRoZSAyMCBNb3N0IFByZWRvbWluYW50IEJpb2xvZ2ljYWwgUHJvY2Vzc2VzIiwgeGxhYiA9ICJCaW9sb2dpY2FsIFByb2Nlc3MiLCB5bGFiID0gIkNvdW50IikKCgojIENyZWF0ZSBhIHNlcGFyYXRlIHBsb3QgZm9yIHRoZSBsZWdlbmQKcG5nKCIuLi9vdXRwdXQvR09sZWdlbmQucG5nIiwgd2lkdGggPSA4MDAsIGhlaWdodCA9IDYwMCkKcGFyKG1hciA9IGMoMCwgMCwgMCwgMCkpCnBsb3QubmV3KCkKbGVnZW5kKCJjZW50ZXIiLCBsZWdlbmQgPSB0b3BfMjBfcHJvY2Vzc2VzJEJpb2xvZ2ljYWxfUHJvY2VzcywgZmlsbCA9IGJhcl9jb2xvcnMsIGNleCA9IDEsIHRpdGxlID0gIkJpb2xvZ2ljYWwgUHJvY2Vzc2VzIikKZGV2Lm9mZigpCmBgYAoKYGBge3IgbGVnZW5kLCBldmFsPVRSVUUsIGZpZy53aWR0aCA9IDEwMCAsZmlnLmhlaWdodCA9IDEwMH0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uL291dHB1dC9HT2xlZ2VuZC5wbmciKQpgYGAKCgoK